﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Wizard.UI;
using System.IO;
using System.Net;
using System.Threading;

namespace RoketPack.Recovery
{
    public partial class CompletePage : ExternalWizardPage
    {
        private RecoveryWizard m_Wizard = null;
        private bool m_SentReport = false;

        public CompletePage(RecoveryWizard wizard)
        {
            InitializeComponent();

            this.m_Wizard = wizard;
        }

        private void CompletePage_SetActive(object sender, CancelEventArgs e)
        {
            this.SetWizardButtons(WizardButtons.Finish ^ WizardButtons.Back);

            this.c_LogDataTextArea.Text = this.m_Wizard.RecoveryData.RecoveryLog;

            if (this.m_Wizard.RecoveryData.CausedByException)
            {
                this.c_RecoveryTypeLabel.Text = @"Recovery mode was initiated because an unexpected
framework exception occurred within RoketPack.

Sending stack trace and exception information allows
the developers to ship updates that prevent these
errors from re-occurring.";
                this.c_SendErrorInformation.Checked = true;
                this.c_SendErrorInformation.Visible = true;
            }
            else
            {
                this.c_RecoveryTypeLabel.Text = @"Recovery mode was initiated because an unexpected
application shutdown (i.e. forcibly terminated
via Task Manager).";
                this.c_SendErrorInformation.Checked = false;
                this.c_SendErrorInformation.Visible = false;
            }
        }

        private void CompletePage_WizardFinish(object sender, CancelEventArgs e)
        {
            if (this.m_SentReport || this.c_SendErrorInformation.Checked == false)
                return;

            // Stop the wizard from closing while we send the report.
            e.Cancel = true;
            this.GetWizard().ControlBox = false;
            this.GetWizard().CancelEnabled = false;
            this.SetWizardButtons(WizardButtons.None);

            ThreadStart lambda = () =>
                {
                    if (File.Exists(RecoveryUtil.RecoveryDataPath))
                        File.Delete(RecoveryUtil.RecoveryDataPath);

                    // Send the information to the web server.
                    byte[] data = Manager.Encoding.GetBytes(System.Web.HttpUtility.UrlEncode(this.CollectData()));
                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://pack.roket-enterprises.com/bugreport");
                    request.Method = "POST";
                    request.Headers.Add("X-Permitted", "true");
                    request.ContentLength = data.Length + 5;
                    request.ContentType = "application/x-www-form-urlencoded";
                    Stream stream = request.GetRequestStream();
                    byte[] prefix = Manager.Encoding.GetBytes("data=");
                    stream.Write(prefix, 0, prefix.Length);
                    stream.Write(data, 0, data.Length);
                    stream.Close();
                    try
                    {
                        WebResponse response = request.GetResponse();
                        string resp = "";
                        byte[] b = new byte[] { 0 };
                        for (int i = 0; i < response.ContentLength; i++)
                        {
                            response.GetResponseStream().Read(b, 0, 1);
                            resp += Manager.Encoding.GetString(b);
                        }
                        response.Close();

                        if (resp != "SUCCESS")
                        {
                            MessageBox.Show("Unable to send error report to server (general error)!", "Error Reporting Failure", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                    catch (WebException ex)
                    {
                        MessageBox.Show("Unable to send error report to server (http status: " + ex.Status.ToString() + "!", "Error Reporting Failure", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }

                    this.m_SentReport = true;

                    RoketPack.Manager.VoidLambda closelambda = () =>
                        {
                            this.GetWizard().Finish();
                        };
                    if (this.GetWizard().InvokeRequired)
                        this.GetWizard().Invoke(closelambda);
                    else
                        closelambda();
                };

            // Start a foreground thread to send off the information.
            Thread thread = new Thread(lambda);
            thread.Name = "Recovery Bug Report";
            thread.Start();
        }

        private void c_DetailsLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            // Show a dialog box that shows all of the exception information.
            ExceptionDetails d = new ExceptionDetails();
            d.Data = CollectData();
            d.ShowDialog();
        }

        private string CollectData()
        {
            return
@"===== Operating System Information =====
OS Name: " + Environment.OSVersion.Platform.ToString() + @"
OS Version: " + Environment.OSVersion.VersionString + @"

===== Exception Information =====
Exception Type: " + this.m_Wizard.RecoveryData.ExceptionType + @"
Exception Message: " + this.m_Wizard.RecoveryData.ExceptionMessage + @"
Exception Source: " + this.m_Wizard.RecoveryData.ExceptionSource + @"
Exception Help Link:" + this.m_Wizard.RecoveryData.ExceptionHelpLink + @"

===== Exception Stacktrace =====
" + this.m_Wizard.RecoveryData.ExceptionType + " \"" + this.m_Wizard.RecoveryData.ExceptionMessage + '\"' + @"
" + this.m_Wizard.RecoveryData.ExceptionStackTrace + @"

===== Recovery Log =====
" + this.m_Wizard.RecoveryData.RecoveryLog + @"
";
        }
    }
}
